library ieee;
 use ieee.std_logic_1164.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
 use ieee.std_logic_arith.all;
 
library work;
    use work.router_pack.all;
    use work.env_pack.all;    

-------------------------------------------------------------------------
    
entity module is
    
port(
   -- General Signals: --
   RESET   		: in std_logic;
   MODULE_ID	   : in std_logic_vector(2*e_coord_position_width_c-1 downto 0);
   BASE_CLK     : in std_logic;
   CLOCK_MULT   : in std_logic_vector(e_clock_mult_width_c-1 downto 0);
   
   -- Input Port i/f: --
   RI      : in std_logic;
   AI      : out std_logic;
   DI      : in std_logic_vector(flit_size_c-1 downto 0);
       
   -- Output Port i/f: --
   RO      : out std_logic;
   AO      : in std_logic;
   DO      : out std_logic_vector(flit_size_c-1 downto 0);
   
   -- Environment Settings --
    WORKLOAD          : in std_logic_vector(e_workload_width_c-1 downto 0);
    MAX_VC            : in std_logic_vector(vc_width-1 downto 0);
    MAX_SL            : in std_logic_vector(msl_ind_width-1 downto 0);
    MAX_PACKET_SIZE   : in std_logic_vector(e_packet_size_width_c-1 downto 0);
    MIN_PACKET_SIZE   : in std_logic_vector(e_packet_size_width_c-1 downto 0);
    SEED1             : in std_logic_vector(e_seed_width_c-1 downto 0);
    SEED2             : in std_logic_vector(e_seed_width_c-1 downto 0)
   );    
    
end module;

-------------------------------------------------------------------------

architecture module_arch of module is

-- Module Components --

component injector
port(
    -- General Signals: --
    RESET           		: in std_logic;
    CLK             		: in std_logic;
    CYCLE_COUNTER   	 : in std_logic_vector(e_cycle_counter_width_c-1 downto 0);
    MODULE_ID		      : in std_logic_vector(2*e_coord_position_width_c-1 downto 0);
    
    -- Output Port i/f: --
    RO      : out std_logic;
    AO      : in std_logic;
    DO      : out std_logic_vector(flit_size_c-1 downto 0);
    
    -- Environment Settings --
    WORKLOAD          : in std_logic_vector(e_workload_width_c-1 downto 0);
    MAX_VC            : in std_logic_vector(vc_width-1 downto 0);
    MAX_SL            : in std_logic_vector(msl_ind_width-1 downto 0);
    MAX_PACKET_SIZE   : in std_logic_vector(e_packet_size_width_c-1 downto 0);
    MIN_PACKET_SIZE   : in std_logic_vector(e_packet_size_width_c-1 downto 0);
    SEED1             : in std_logic_vector(e_seed_width_c-1 downto 0);
    SEED2             : in std_logic_vector(e_seed_width_c-1 downto 0)
); 
end component;

component collector
port(
    -- General Signals: --
    RESET           		: in std_logic;
    CLK             		: in std_logic;
    CYCLE_COUNTER    	: in std_logic_vector(e_cycle_counter_width_c-1 downto 0);
    MODULE_ID		      : in std_logic_vector(2*e_coord_position_width_c-1 downto 0);
    
    -- Input Port i/f: --
    RI      : in std_logic;
    AI      : out std_logic;
    DI      : in std_logic_vector(flit_size_c-1 downto 0)
);
end component;

-- Internal Signals --
signal clk            	  : std_logic := '0';
signal cycle_counter     : std_logic_vector(e_cycle_counter_width_c-1 downto 0) := conv_std_logic_vector(0, e_cycle_counter_width_c);


-- Module Implementation --
begin
   
    clk_calc : process (BASE_CLK)
	variable base_clk_count  : integer := 0;
    begin
    	base_clk_count := (base_clk_count + 1) mod (conv_integer(CLOCK_MULT));
    	if (base_clk_count = 0 ) then
    		clk <= not clk;   	
    	end if;
    	
    	if (BASE_CLK'event) and (BASE_CLK = '1') then
    		cycle_counter <= cycle_counter + conv_std_logic_vector(1, e_cycle_counter_width_c);
    	end if;
    	
    end process;
    
    
    u_injector: injector
    port map(
        RESET           	=> RESET,
        CLK            	 => clk,
        CYCLE_COUNTER	   => cycle_counter,
	MODULE_ID 	      =>  MODULE_ID,
	     
        RO              	=> RO,
        AO              	=> AO,
        DO              	=> DO,
        
        WORKLOAD         => WORKLOAD,
        MAX_VC           => MAX_VC,
        MAX_SL           => MAX_SL,
        MAX_PACKET_SIZE  => MAX_PACKET_SIZE,
        MIN_PACKET_SIZE  => MIN_PACKET_SIZE,
        SEED1			 => SEED1,
        SEED2			 => SEED2
    );
    
    u_collector: collector
    port map(
        RESET           	=> RESET,
        CLK             	=> clk,
        CYCLE_COUNTER 	  => cycle_counter,
	MODULE_ID 	      => MODULE_ID,
        RI              	=> RI,
        AI              	=> AI,
        DI              	=> DI
    );
    
end module_arch;
